package com.acxy.ants.resful;

import com.acxy.ants.resful.annotation.API;
import com.acxy.ants.common.enums.RequestMethod;
import com.acxy.ants.core.AnnotationBinding;
import com.acxy.ants.common.kit.StrKit;
import com.acxy.ants.resful.annotation.Controller;
import com.acxy.ants.resful.annotation.GET;
import com.acxy.ants.resful.annotation.POST;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * @author MrShun
 * @version 1.0
 * @Date 2017-04-27
 */
public class ActionInitialization {

    /**
     * 获取classList里面的信息放回请求集合对象
     *
     * @param classList 保存加了Controller的类
     */
    public static List<RequestMapping> getRequestMappingList(List<Class<?>> classList, String regexSuffix, String moduleName) {
        List<RequestMapping> mappings = new ArrayList<>();
        List<String> keys = new ArrayList<>();
        for (Class<?> classes : classList) {
            Object object = null;
            try {
                object = classes.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            Controller controller = classes.getAnnotation(Controller.class);
            String convalue = "";
            if (controller != null && controller.value() != null && !"".equals(controller.value()))
                convalue = controller.value();
            //得到该类下面的所有方法
            Method[] methods = classes.getDeclaredMethods();
            //================== 处理方法注解信息 ================
            for (Method method : methods) {
                //排除静态方法和私有方法
                if(!Modifier.isStatic(method.getModifiers()) && !method.getClass().isPrimitive()){
                    RequestMethod requestType = null;
                    String[] mappingValues = {};
                    //得到该类下面的RequestMapping注解
                    POST postMapping = method.getAnnotation(POST.class);
                    if (null != postMapping) { //处理POST注解
                        requestType = RequestMethod.POST;
                        String[] values = postMapping.value();
                        mappingValues = values.length == 0 ? new String[]{method.getName()} : values;
                    } else {
                        GET getMapping = method.getAnnotation(GET.class);
                        if (null != getMapping) { //处理GET注解
                            requestType = RequestMethod.GET;
                            String[] values = getMapping.value();
                            mappingValues = values.length == 0 ? new String[]{method.getName()} : values;
                        } else {
                            API apiMapping = method.getAnnotation(API.class);
                            if (null != apiMapping) { //处理API注解
                                requestType = RequestMethod.API;
                                String[] values = apiMapping.value();
                                mappingValues = values.length == 0 ? new String[]{method.getName()} : values;
                            } else { //处理当没有请求类型注解时用默认方法代替URL
                                mappingValues = new String[]{method.getName()};
                            }
                        }
                    }
                    String[] urls = StrKit.formatURLs(mappingValues, regexSuffix);
                    urls = join(convalue, urls);
                    RequestMapping mapping = new RequestMapping(urls, null, requestType, object, method, moduleName);
                    for (String key : urls) {
                        if (keys.contains(key)) throw new RuntimeException(key + " 存在相同的URL链接, 初始化失败!");
                        keys.add(key);
                    }
                    mappings.add(mapping);
                }
            }
            //================== 处理实例化类里面的属性注解信息 ================
            AnnotationBinding.initFiledValues(object);
        }
        return mappings;
    }


    /**
     * 往urls数组里面放入注解值
     *
     * @param str  注解值
     * @param urls url数组
     * @return
     */
    private static String[] join(String str, String[] urls) {
        if (str.indexOf('/') != 0 && !"".equals(str))
            str = "/" + str;
        for (int i = 0; i < urls.length; i++) {
            urls[i] = str.trim() + urls[i];
        }
        return urls;
    }
}
